#include "Python.h"
#include <QCoreApplication>
#include <iostream>
#include <QImage>
#include <QTimer>
#include <QFile>
#include <QDir>
#include <QLocalServer>
#include <QLocalSocket>
#include <QElapsedTimer>
#include <signal.h>
#include <QJsonArray>
#include <QJsonObject>
#include <QJsonDocument>

QLocalServer *server;
QLocalSocket *currentSocket;
PyObject *pFunc;
pid_t pidA;

uint64_t getCurrentMillis() {
    // 获取当前时间点
    auto now = std::chrono::system_clock::now();
    // 将时间点转换为自纪元以来的持续时间
    auto duration_since_epoch = now.time_since_epoch();
    // 将持续时间转换为毫秒
    auto millis = std::chrono::duration_cast<std::chrono::milliseconds>(duration_since_epoch).count();
    return millis;
}

void handlePythonResult(PyObject *pResult) {


    const char *jsonCStr = PyUnicode_AsUTF8(pResult);
    if (!jsonCStr) {
        qDebug() << "Failed to convert Python JSON string to C string!";
        Py_DECREF(pResult);
        return;
    }

    QByteArray jsonByteArray = QByteArray(jsonCStr);
    QJsonDocument jsonDoc = QJsonDocument::fromJson(jsonByteArray);
    if (jsonDoc.isNull()) {
        qDebug() << "Failed to parse JSON data!";
        Py_DECREF(pResult);
        return;
    }

    QString response = jsonDoc.toJson(QJsonDocument::Compact) + "<END>";
//    qDebug() << response;

    Py_DECREF(pResult);
//    std::cout << "socketPro-->response:" << response.toStdString() << std::endl;
    currentSocket->write(response.toUtf8());
    currentSocket->flush();

}

void checkProcessA() {
    // 检查进程 A 是否存在
    if (kill(pidA, 0) != 0) {
        // 进程 A 不存在，终止进程 B
        std::cerr << "Process " << pidA << " has terminated. Exiting..." << std::endl;
        QCoreApplication::quit(); // Terminate the application
    }
}

void processImageData(const QByteArray &imageData) {

    // 将 imageData 转换为 Python 字节对象
    PyObject *pImageBytes = PyBytes_FromStringAndSize(imageData.constData(), imageData.size());
    PyObject *pBool = PyBool_FromLong(false);
    PyObject *pArgs = PyTuple_Pack(2, pImageBytes, pBool);

    if (!pArgs) {
        std::cerr << "socketPro-->Failed to pack arguments for Python function" << std::endl;
        Py_DECREF(pImageBytes);
        Py_DECREF(pBool);
        return;
    }

    // 调用 Python 函数
    PyObject *pResult = PyObject_CallObject(pFunc, pArgs);
//    Py_DECREF(PyTuple_GetItem(pArgs, 0));
//    Py_DECREF(PyTuple_GetItem(pArgs, 1));
    Py_DECREF(pImageBytes);
    Py_DECREF(pBool);
    Py_DECREF(pArgs);

    // 处理 Python 函数返回结果
    handlePythonResult(pResult);

    // 清除 imageData
    const_cast<QByteArray &>(imageData).clear();
}


void handleNewConnection() {
    std::cerr << "注册handleNewConnection" << std::endl;
    currentSocket = server->nextPendingConnection();
    if (!currentSocket)
        return;
    QObject::connect(currentSocket, &QLocalSocket::readyRead, []() {
        std::cerr << "数据数据" << getCurrentMillis() << std::endl;
        static qint64 imageSize = -1;  // 保存图像大小
        static QByteArray imageData;   // 用于存储图像数据
        static bool flag = false;
        while (currentSocket->bytesAvailable() > 0) {
            // 如果图像大小未读取，先读取图像大小
            if (imageSize == -1) {
                if (currentSocket->bytesAvailable() < sizeof(flag)) return;
                currentSocket->read(reinterpret_cast<char *>(&flag), sizeof(flag));
                qDebug() << "Received flag:" << flag;


                if (currentSocket->bytesAvailable() < sizeof(imageSize))
                    return;  // 等待足够的数据来读取图像大小

                currentSocket->read(reinterpret_cast<char *>(&imageSize), sizeof(imageSize));
                imageData.clear();  // 清空图像数据缓冲区
                std::cerr << "Image size to receive: " << imageSize << std::endl;
            }

            // 读取图像数据
            qint64 bytesToRead = std::min(imageSize - imageData.size(), currentSocket->bytesAvailable());
            imageData.append(currentSocket->read(bytesToRead));

            // 检查是否接收完图像
            if (imageData.size() == imageSize) {
                std::cerr << "Image received successfully, size: " << imageSize << std::endl;
                processImageData(imageData);
//                // 处理接收到的图像数据（例如，将其转换为 QImage 或其他处理）
//                QImage image;
//                image.loadFromData(imageData, "BMP");
//                if (!image.save("/Users/zhanghongwei/Desktop/aaa/socket-project/received_image.bmp", "BMP")) {
//                    std::cerr << "Failed to save image to local file" << std::endl;
//                } else {
//                    std::cerr << "Image saved successfully to /path/to/save/received_image.bmp" << std::endl;
//                }

                // 清空状态，以便下一次传输
                imageSize = -1;
//                imageData.clear();
            }
        }
    });
}

void initializePython(const std::string &pythonPath) {
    Py_Initialize();
    if (!Py_IsInitialized()) {
        std::cerr << "socketPro-->python fail" << std::endl;
        exit(-1);
    }
    std::string pythonCode = "import sys\nsys.path.append('" + pythonPath + "')\n";
    PyRun_SimpleString(pythonCode.c_str());
    PyObject *pModule = PyImport_ImportModule("track");
    if (!pModule) {
        PyErr_Print();
        std::cerr << "socketPro-->loaded gesture.py fail" << std::endl;
        exit(-1);
    }
    pFunc = PyObject_GetAttrString(pModule, "process_touch");
    if (!pFunc || !PyCallable_Check(pFunc)) {
        PyErr_Print();
        std::cerr << "socketPro-->cannot find function process_touch" << std::endl;
        Py_DECREF(pModule);
        exit(-1);
    }
    std::cout << "socketPro-->loaded xxx.py success" << std::endl;
    PyObject *pDirFunc = PyObject_GetAttrString(pModule, "current_directory");
    if (pDirFunc && PyCallable_Check(pDirFunc)) {
        PyObject *pDirResult = PyObject_CallObject(pDirFunc, nullptr);
        if (pDirResult) {
            const char *dir = PyUnicode_AsUTF8(pDirResult);
            std::cout << "socketPro-->Current directory: " << dir << std::endl;
            Py_DECREF(pDirResult);
        } else {
            PyErr_Print();
            std::cerr << "socketPro-->Failed to call current_directory" << std::endl;
        }
        Py_DECREF(pDirFunc);
    } else {
        PyErr_Print();
        std::cerr << "socketPro-->cannot find function current_directory" << std::endl;
        Py_XDECREF(pDirFunc);
    }
//    Py_DECREF(pModule);
}

int main(int argc, char **argv) {
    QCoreApplication app(argc, argv);
    std::cout << "socketPro-->starting process" << std::endl;
    QString processId = (argc > 1) ? QString(argv[1]) : "socketHandPro23043";
//    QString path = (argc > 2) ? QString(argv[2]) : "/data/app/xth/socket-temp/socket-project/res/track";
    QString path = (argc > 2) ? QString(argv[2]) : "/Users/zhanghongwei/Desktop/socket-temp/socket-project/res/track";
    if (processId.isEmpty()) {
        std::cerr << "socketPro-->processId is empty" << std::endl;
        return -1;
    }
    QString prefix = "socketHandPro";
    if (processId.startsWith(prefix)) {
        QString pidString = processId.mid(prefix.length()); // 去掉前缀
        bool ok;
        pidA = pidString.toInt(&ok);
        if (!ok) {
            std::cerr << "socketPro-->Failed to convert PID from string" << std::endl;
            return -1;
        }
        std::cout << "Extracted PID: " << pidA << std::endl;
    } else {
        std::cerr << "socketPro-->processId does not start with the expected prefix" << std::endl;
        return -1;
    }
    //socketHandPro23043
    std::cout << "socketPro-->processId id:" << processId.toStdString() << std::endl;
    // 获取当前应用程序的全路径
    QString fullPath = QCoreApplication::applicationFilePath();
    std::cout << "socketPro-->Application full path:" << fullPath.toStdString() << std::endl;
    // 获取当前应用程序所在的目录
    QString appDir = QCoreApplication::applicationDirPath();
    std::cout << "socketPro-->Application directory:" << appDir.toStdString() << "\n" << std::endl;
    // 加载python
//    QString absolutePythonPath = QDir(appDir).absoluteFilePath("../python");
    QString absolutePythonPath = path;
    std::cout << "socketPro-->absolutePythonPath:" << absolutePythonPath.toStdString() << std::endl;
    initializePython(absolutePythonPath.toStdString());
    // 建立本地连接
    QString socketPath = QDir::temp().absoluteFilePath(processId);
    if (QFile::exists(socketPath)) {
        std::cout << "Delete old socket files" << std::endl;
        QFile::remove(socketPath);
    }
    server = new QLocalServer();
    server->listen(processId);
    QObject::connect(server, &QLocalServer::newConnection, handleNewConnection);
    if (!server->isListening()) {
        std::cerr << "Unable to start the server:" << server->errorString().toStdString() << std::endl;
        return -1;
    }

    std::cout << "Server started successfully!" << getCurrentMillis() << std::endl;




//    QTimer *timer = new QTimer();
//    QObject::connect(timer, &QTimer::timeout, &checkProcessA);
//    timer->start(10000); // Check every 5 seconds
    return app.exec();
}





